(function(){
    var Gallery = {
        Editor: null,

        icons: 'gallery',
        lang:  ['sr'],
        init: function(editor) {
            this.Editor = editor;

            this.addCommand();
            this.addButton();
            this.initDoubleClick();
        },
        afterInit: function(editor) {
            var dataProcessor = editor.dataProcessor;
            var htmlFilter    = dataProcessor && dataProcessor.htmlFilter;
            var dataFilter    = dataProcessor && dataProcessor.dataFilter;

            // entering Design view
            if (dataFilter) {
                dataFilter.addRules({
                    elements: {
                        ul: function(ul) {
                            if (ul.classes.indexOf('photo-gallery') >= 0) {
                                var data = JSON.parse(ul.children[0].getHtml());
                                var li, images = [];
                                for (var i=1; i<ul.children.length; i++) {
                                    li = ul.children[i];
                                    images.push(li.children[0].attributes.src);
                                }

                                var fakeImage = createFakeElement(editor, {
                                    element: ul,
                                    width: data.width,
                                    height: data.height,
                                    align: data.align,
                                    images: data.images
                                }, true);

                                return fakeImage;
                            }
                        }
                    }
                });
            }
            // entering HTML-code view
            if (htmlFilter) {
                htmlFilter.addRules({
                    elements: {
                        img: function(element) {
                            if (element.hasClass('photo-gallery')) {
                                var images = element.attributes['data-images'].split(",");
                                var width  = element.attributes.width
                                var height = element.attributes.height
                                var align  = element.attributes.align
                                var id     = element.attributes.id ? element.attributes.id : generateId();
                                var className = '';
                                switch (images.length) {
                                    case 2:
                                        className = 'count-2';
                                        break;
                                    case 3:
                                        className = 'count-3';
                                        break;
                                    default:
                                        if (images.length>3) {
                                            className = 'count-n';
                                        }
                                        break;
                                }
                                var li, ul = new CKEDITOR.htmlParser.element('ul', {
                                    'class': 'photo-gallery' + (className ? ' '+className : ''),
                                    'id': id
                                });
                                
                                // create util li
                                li = new CKEDITOR.htmlParser.element('li', {class: 'data'});
                                var data = {
                                    width: width,
                                    height: height,
                                    align: align,
                                    images: images
                                }
                                li.setHtml(JSON.stringify(data));
                                ul.add(li);

                                // add javascript
                                var script = new CKEDITOR.htmlParser.element('script', {
                                    type: 'text/javascript',
                                    src:  getPluginPath() + '/gallery.js'
                                });
                                li.add(script);

                                // add css
                                var style = new CKEDITOR.htmlParser.element('link', {
                                    type: 'text/css',
                                    rel:  'stylesheet',
                                    href: getPluginPath() + '/gallery.css'
                                });
                                li.add(style);

                                for (var i=0; i<images.length; i++) {
                                    if (images[i].length>0) {
                                        li = new CKEDITOR.htmlParser.element('li');
                                        li.setHtml('<img src="'+images[i]+'">');
                                        ul.add(li);
                                    }
                                }
                                return ul;
                            }
                        }
                    }
                })
            }
        },
        addCommand: function() {
            this.Editor.addCommand('galleryDialogMain', new CKEDITOR.dialogCommand('galleryDialogMain',{
                allowedContent: '*',
                requires: ['fakeobjects']
            }));
        },
        addButton: function() {
            var e    = this.Editor;
            var lang = e.lang.gallery;

            e.ui.addButton('Gallery', {
                label:   lang.photoGallery,
                command: 'galleryDialogMain',
                toolbar: 'insert'
            });
        },
        getDialog: function(name) {
            return this.path + '/dialogs/' + name + '.js';
        },
        initDoubleClick: function() {
            this.Editor.on('doubleclick', function(e){
                var element = e.data.element;
                if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'gallery' )
                    e.data.dialog = 'galleryDialogMain';
            });
        }
    };

    CKEDITOR.plugins.add('gallery', Gallery);
    CKEDITOR.dialog.add('galleryDialogMain', Gallery.getDialog('main'));
})();

function createFakeElement(editor, data, parser) {
    var pluginPath = getPluginPath();
    var el         = data.element;
    var plugin     = getPlugin();
    var lang       = plugin.langEntries[plugin.lang];
    editor.lang.fakeobjects['gallery'] = lang.gallery;

    var css = {
        border: "1px solid #777",
        background: "#eee url(" + pluginPath + "/icons/gallery.png) no-repeat center center"
    };

    var id = el.id ? el.id : generateId();

    var fakeImage;
    if (parser) {
        fakeImage = editor.createFakeParserElement(el, 'cke_gallery', 'gallery', true);
        fakeImage.attributes['class']  = 'photo-gallery';
        fakeImage.attributes['width']  = data.width;
        fakeImage.attributes['height'] = data.height;
        fakeImage.attributes['align']  = data.align;
        fakeImage.attributes['style']  = "border:" + css.border + ';background:' + css.background;
        fakeImage.attributes['data-images'] = data.images.join(',')
        fakeImage.attributes['id'] = id;

    } else {
        fakeImage = editor.createFakeElement(el, 'cke_gallery', 'gallery', true);
        fakeImage.setAttributes({
            'class': 'photo-gallery',
             width:  data.width,
             height: data.height,
             align:  data.align,
             id: id
        });
        fakeImage.setStyles(css);
        fakeImage.data('images', data.images.join(','));
    }
    
    return fakeImage;
}
function getPluginPath() {
    return getPlugin().path.replace(/\/$/, '');
}
function getPlugin() {
    return CKEDITOR.plugins.get('gallery');
}
function generateId() {
    var buffer = 'qwertyuiopasdfghjklzxcvbnm0123456789';
    var id='';
    for (var i=0; i<10; i++) {
        id += buffer.substr(Math.floor(Math.random() * (buffer.length-1)), 1);
    }
    return id;
}